package com.hfjava.demo.util.wxpay;

import com.hfjava.demo.util.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @description: 微信App支付
 * @author: qiu bo yang
 * @create: 2020-03-16 10:48
 */
@Slf4j
public class WxPay {
    //应用ID
    private static final String appId = "";
    //商户号
    private static final String mchId = "";
    //通知地址
    private static final String notifyUrl = "";
    //支付类型
    private static final String tradeType = "APP";
    //发起微信地址
    private static final String orderApplyUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    // 微信API安全key
    public static final String key = "";
    //支付成功回调地址
    private static final String redirectUrl = "";

    /**
     * 发送微信APP订单请求
     *
     * @param nonceStr       随机字符串
     * @param body           商品描述
     * @param outTradeNo     商户订单号
     * @param totalFee       金额 分
     * @param spbillCreateIp 终端ip
     * @return
     */
    public static String sendWxOrder(String nonceStr, String body, String outTradeNo, String totalFee, String spbillCreateIp) {
        Map<String, String> map = new HashMap<>();
        map.put("nonce_str", nonceStr);
        map.put("body", body);
        map.put("out_trade_no", outTradeNo);
        map.put("total_fee", totalFee);
        map.put("spbill_create_ip", spbillCreateIp);
        map.put("appid", appId);
        map.put("mch_id", mchId);
        map.put("notify_url", notifyUrl);
        map.put("trade_type", tradeType);
        // 拼接key成为签名原串
        String signStr = getParamStr(map) + "&key=" + key;
        String sign = MD5Tool.encoding(signStr).toUpperCase();
        //log.info("---------sign：{}", sign);
        map.put("sign", sign);
        String requestParam = XmlUtil.mapToXml(map);
        String result = HttpUtils.sendPostParam(orderApplyUrl, requestParam);
        //请求结果
        //log.info("请求结果：{}", result);
        Map<String, String> resultMap = XmlUtil.xmlToMap(result);
        if ("SUCCESS".equals(resultMap.get("return_code"))) {
            String resultStr = resultMap.get("mweb_url");
            resultStr += "&redirect_url=" + URLEncoder.encode(redirectUrl);
            return resultStr;
        } else {
            return null;
        }
    }

    /**
     * 微信验签
     *
     * @param map
     * @return
     */
    public static Boolean signCheck(TreeMap<String, String> map) {
        String sign = map.get("sign");
        map.remove("sign");
        // 拼接key成为签名原串
        String signStr = getParamStr(map) + "&key=" + key;
        //log.info("---------signStr：{}", signStr);
        // 将需要签名的字符串md5并全部转换成大写
        String newSign = MD5Tool.encoding(signStr).toUpperCase();
        if (sign.equals(newSign)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取签名字符串
     *
     * @param map
     * @return
     */
    private static String getParamStr(Map<String, String> map) {
        StringBuffer stringBuffer = new StringBuffer();
        for (String key : map.keySet()) {
            String value = map.get(key);
            // 空值不传递，不签名
            if (StringUtils.isNotEmpty(value)) {
                // 签名原串，不url编码
                stringBuffer.append(key + "=" + value + "&");
            }
        }
        // 去掉最后一个&
        String result = stringBuffer.substring(0, stringBuffer.length() - 1);
        return result;
    }
}
